from pydantic import BaseModel, EmailStr, validator
from typing import Optional, List
from datetime import datetime, date
from enum import Enum

# 枚举类型定义
class WorkCategory(str, Enum):
    """作品分类枚举"""
    IMAGE = "image"
    VIDEO = "video"
    MUSIC = "music"
    TEXT = "text"

class ContestStatus(str, Enum):
    """竞赛状态枚举"""
    UPCOMING = "upcoming"
    ONGOING = "ongoing"
    ENDED = "ended"

class QRStatus(str, Enum):
    """二维码状态枚举"""
    WAITING = "waiting"
    SCANNED = "scanned"
    SUCCESS = "success"
    EXPIRED = "expired"

# 通用响应模式
class ResponseModel(BaseModel):
    """通用API响应模式"""
    code: int = 200
    message: str = "success"
    data: Optional[dict] = None

# 用户相关模式
class UserBase(BaseModel):
    """用户基础信息"""
    username: str
    email: EmailStr
    nickname: Optional[str] = None

class UserCreate(UserBase):
    """用户注册请求"""
    password: str
    
    @validator('password')
    def validate_password(cls, v):
        if len(v) < 6:
            raise ValueError('密码长度不能少于6位')
        return v

class UserLogin(BaseModel):
    """用户登录请求"""
    username: str
    password: str

class UserUpdate(BaseModel):
    """用户信息更新请求"""
    nickname: Optional[str] = None
    email: Optional[EmailStr] = None
    avatar: Optional[str] = None
    phone: Optional[str] = None
    real_name: Optional[str] = None
    
    @validator('phone')
    def validate_phone(cls, v):
        if v and not v.isdigit():
            raise ValueError('手机号只能包含数字')
        if v and len(v) != 11:
            raise ValueError('手机号必须是11位数字')
        return v
    
    @validator('real_name')
    def validate_real_name(cls, v):
        if v and len(v) > 50:
            raise ValueError('真实姓名不能超过50个字符')
        return v

class UserResponse(UserBase):
    """用户信息响应"""
    id: int
    avatar: Optional[str] = None
    phone: Optional[str] = None
    real_name: Optional[str] = None
    email_verified: bool = False
    phone_verified: bool = False
    real_name_verified: bool = False
    created_at: datetime
    
    class Config:
        from_attributes = True

class UserLoginResponse(UserResponse):
    """用户登录响应"""
    token: str

# 作品相关模式
class WorkBase(BaseModel):
    """作品基础信息"""
    title: str
    description: Optional[str] = None
    category: WorkCategory
    tags: Optional[List[str]] = []

class WorkCreate(WorkBase):
    """作品创建请求"""
    pass

class WorkUpdate(BaseModel):
    """作品更新请求"""
    title: Optional[str] = None
    description: Optional[str] = None
    tags: Optional[List[str]] = None

class WorkResponse(WorkBase):
    """作品信息响应"""
    id: int
    file_url: str
    thumbnail: Optional[str] = None
    views: int = 0
    likes: int = 0
    comments: int = 0
    user_id: int
    created_at: datetime
    updated_at: Optional[datetime] = None
    
    class Config:
        from_attributes = True

class WorkListResponse(BaseModel):
    """作品列表响应"""
    total: int
    page: int
    limit: int
    works: List[WorkResponse]

# 竞赛相关模式
class ContestBase(BaseModel):
    """竞赛基础信息"""
    title: str
    description: Optional[str] = None
    rules: Optional[str] = None
    start_date: date
    end_date: date
    prize: Optional[str] = None
    organizer: Optional[str] = None
    category: Optional[str] = None

class ContestCreate(ContestBase):
    """竞赛创建请求"""
    pass

class ContestResponse(ContestBase):
    """竞赛信息响应"""
    id: int
    status: ContestStatus
    participant_count: int = 0
    created_at: datetime
    
    class Config:
        from_attributes = True

class ContestListResponse(BaseModel):
    """竞赛列表响应"""
    total: int
    page: int
    limit: int
    contests: List[ContestResponse]

# AI工具相关模式
class AIToolBase(BaseModel):
    """AI工具基础信息"""
    name: str
    description: Optional[str] = None
    icon: Optional[str] = None
    url: str
    category: str
    tags: Optional[List[str]] = []

class AIToolCreate(AIToolBase):
    """AI工具创建请求"""
    rating: Optional[int] = 0
    popularity: Optional[int] = 0

class AIToolResponse(AIToolBase):
    """AI工具信息响应"""
    id: int
    rating: float  # 显示时除以10
    popularity: int
    
    @validator('rating', pre=True)
    def convert_rating(cls, v):
        return v / 10.0 if isinstance(v, int) else v
    
    class Config:
        from_attributes = True

class AIToolSearchResponse(BaseModel):
    """AI工具搜索响应"""
    total: int
    page: int
    limit: int
    results: List[AIToolResponse]

# 微信登录相关模式
class WeChatQRResponse(BaseModel):
    """微信二维码响应"""
    qr_code: str
    qr_id: str
    expire_time: int

class WeChatScanStatusResponse(BaseModel):
    """微信扫码状态响应"""
    status: QRStatus
    user: Optional[UserLoginResponse] = None

# 文件上传相关模式
class FileUploadResponse(BaseModel):
    """文件上传响应"""
    url: str
    thumbnail: Optional[str] = None
    size: Optional[int] = None
    mime_type: Optional[str] = None

# 搜索相关模式
class TrendingResponse(BaseModel):
    """热门搜索响应"""
    keywords: List[str]

# 竞赛作品相关模式
class ContestWorkResponse(WorkBase):
    """竞赛作品信息响应"""
    id: int
    file_url: str
    thumbnail: Optional[str] = None
    views: int = 0
    likes: int = 0
    comments: int = 0
    user_id: int
    contest_id: Optional[int] = None
    created_at: datetime
    updated_at: Optional[datetime] = None
    
    # 用户信息
    user: Optional[dict] = None
    
    # 是否已点赞/收藏
    is_liked: Optional[bool] = False
    is_favorited: Optional[bool] = False
    
    class Config:
        from_attributes = True

class ContestWorkListResponse(BaseModel):
    """竞赛作品列表响应"""
    total: int
    page: int
    limit: int
    works: List[ContestWorkResponse]

# 点赞相关模式
class WorkLikeResponse(BaseModel):
    """作品点赞响应"""
    is_liked: bool
    likes_count: int

# 收藏相关模式
class WorkFavoriteResponse(BaseModel):
    """作品收藏响应"""
    is_favorited: bool
    favorites_count: int

# 评论相关模式
class CommentCreate(BaseModel):
    """评论创建请求"""
    content: str
    parent_id: Optional[int] = None
    
    @validator('content')
    def validate_content(cls, v):
        if not v or len(v.strip()) == 0:
            raise ValueError('评论内容不能为空')
        if len(v) > 1000:
            raise ValueError('评论内容不能超过1000字符')
        return v.strip()

class CommentResponse(BaseModel):
    """评论信息响应"""
    id: int
    content: str
    user_id: int
    work_id: int
    parent_id: Optional[int] = None
    created_at: datetime
    updated_at: Optional[datetime] = None
    
    # 用户信息
    user: Optional[dict] = None
    
    # 回复列表
    replies: Optional[List['CommentResponse']] = []
    
    class Config:
        from_attributes = True

class CommentListResponse(BaseModel):
    """评论列表响应"""
    total: int
    page: int
    limit: int
    comments: List[CommentResponse]

# 竞赛参与相关模式
class ContestJoinResponse(BaseModel):
    """竞赛参与响应"""
    success: bool
    message: str
    participant_id: Optional[int] = None
    status: str  # joined/already_joined/contest_ended

class ContestParticipantResponse(BaseModel):
    """竞赛参与者信息响应"""
    id: int
    user_id: int
    contest_id: int
    status: str
    created_at: datetime
    
    # 用户信息
    user: Optional[dict] = None
    
    class Config:
        from_attributes = True

# 作品提交相关模式
class WorkSubmitRequest(BaseModel):
    """作品提交请求"""
    title: str
    description: Optional[str] = None
    file_url: str
    thumbnail: Optional[str] = None
    
    @validator('title')
    def validate_title(cls, v):
        if not v or len(v.strip()) == 0:
            raise ValueError('作品标题不能为空')
        if len(v) > 100:
            raise ValueError('作品标题不能超过100字符')
        return v.strip()
    
    @validator('file_url')
    def validate_file_url(cls, v):
        if not v or len(v.strip()) == 0:
            raise ValueError('作品文件URL不能为空')
        return v.strip()

class WorkSubmitResponse(BaseModel):
    """作品提交响应"""
    success: bool
    message: str
    work_id: Optional[int] = None
    work: Optional[ContestWorkResponse] = None

# 作品转发相关模式
class WorkShareRequest(BaseModel):
    """作品转发请求"""
    platform: str  # wechat/weibo/qq/link
    comment: Optional[str] = None
    
    @validator('platform')
    def validate_platform(cls, v):
        allowed_platforms = ['wechat', 'weibo', 'qq', 'link']
        if v not in allowed_platforms:
            raise ValueError(f'转发平台必须是以下之一: {", ".join(allowed_platforms)}')
        return v
    
    @validator('comment')
    def validate_comment(cls, v):
        if v and len(v) > 200:
            raise ValueError('转发备注不能超过200字符')
        return v.strip() if v else None

class WorkShareResponse(BaseModel):
    """作品转发响应"""
    success: bool
    message: str
    share_id: Optional[int] = None
    share_url: Optional[str] = None  # 生成的分享链接

# 分页参数
class PaginationParams(BaseModel):
    """分页参数"""
    page: int = 1
    limit: int = 10
    
    @validator('page')
    def validate_page(cls, v):
        if v < 1:
            raise ValueError('页码必须大于0')
        return v
    
    @validator('limit')
    def validate_limit(cls, v):
        if v < 1 or v > 100:
            raise ValueError('每页数量必须在1-100之间')
        return v

# 认证相关模式
class EmailVerificationRequest(BaseModel):
    """邮箱认证请求"""
    email: EmailStr

class EmailVerificationConfirm(BaseModel):
    """邮箱认证确认"""
    email: EmailStr
    code: str
    
    @validator('code')
    def validate_code(cls, v):
        if not v or len(v) != 6:
            raise ValueError('验证码必须是6位数字')
        if not v.isdigit():
            raise ValueError('验证码只能包含数字')
        return v

class PhoneVerificationRequest(BaseModel):
    """手机认证请求"""
    phone: str
    
    @validator('phone')
    def validate_phone(cls, v):
        if not v.isdigit():
            raise ValueError('手机号只能包含数字')
        if len(v) != 11:
            raise ValueError('手机号必须是11位数字')
        return v

class PhoneVerificationConfirm(BaseModel):
    """手机认证确认"""
    phone: str
    code: str
    
    @validator('phone')
    def validate_phone(cls, v):
        if not v.isdigit():
            raise ValueError('手机号只能包含数字')
        if len(v) != 11:
            raise ValueError('手机号必须是11位数字')
        return v
    
    @validator('code')
    def validate_code(cls, v):
        if not v or len(v) != 6:
            raise ValueError('验证码必须是6位数字')
        if not v.isdigit():
            raise ValueError('验证码只能包含数字')
        return v

class RealNameVerificationRequest(BaseModel):
    """实名认证请求"""
    real_name: str
    id_card: str
    
    @validator('real_name')
    def validate_real_name(cls, v):
        if not v or len(v.strip()) == 0:
            raise ValueError('真实姓名不能为空')
        if len(v) > 50:
            raise ValueError('真实姓名不能超过50个字符')
        return v.strip()
    
    @validator('id_card')
    def validate_id_card(cls, v):
        if not v or len(v) != 18:
            raise ValueError('身份证号必须是18位')
        # 简单的身份证号格式验证
        if not (v[:17].isdigit() and (v[17].isdigit() or v[17].upper() == 'X')):
            raise ValueError('身份证号格式不正确')
        return v.upper()

class VerificationResponse(BaseModel):
    """认证响应"""
    success: bool
    message: str
    verified: Optional[bool] = None